﻿using System;
using System.Reflection;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            //Console.WriteLine("Hello World!");

            //IServiceProvider serviceProvider = new ServiceCollection()
            //                                .AddTransient(typeof(IFoo<>), typeof(Foo<>))
            //                                .AddTransient<IBar, Bar>()
            //                                //.AddTransient(typeof(IFoobar<,>), typeof(Foobar<,>))
            //                                .BuildServiceProvider();

            //Console.WriteLine("serviceProvider.GetService<IFoo<>>(): {0}", serviceProvider.GetService<IFoo<string>>());

            //Console.WriteLine("serviceProvider.GetService<IFoobar<IFoo, IBar>>().Foo: {0}", serviceProvider.GetService<IFoobar<IFoo, IBar>>().Foo);
            //Console.WriteLine("serviceProvider.GetService<IFoobar<IFoo, IBar>>().Bar: {0}", serviceProvider.GetService<IFoobar<IFoo, IBar>>().Bar);

            IServiceCollection services = new ServiceCollection();
            IServiceProvider serviceProvider = RegisterAutofac(services);

            Console.WriteLine("serviceProvider.GetService<IFoo<>>(): {0}", serviceProvider.GetService<IFoo<Test>>());

            IFoo<Test> te = new Foo<Test>();


            Console.ReadKey();
        }

        private static IServiceProvider RegisterAutofac(IServiceCollection services)
        {
            //实例化Autofac容器
            var builder = new ContainerBuilder();
            //将Services中的服务填充到Autofac中
            builder.Populate(services);

            //新模块组件注册    
            builder.RegisterModule<AutofacModuleRegister>();

            //创建容器
            var Container = builder.Build();
            //第三方IOC接管 core内置DI容器 
            return new AutofacServiceProvider(Container);
        }

        public class AutofacModuleRegister : Autofac.Module
        {
            //重写Autofac管道Load方法，在这里注册注入
            protected override void Load(ContainerBuilder builder)
            {
                ////注册Service中的对象,Service中的类要以Service结尾，否则注册失败
                //builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Service")).Where(a => a.Name.EndsWith("Service")).AsImplementedInterfaces();
                ////注册Repository中的对象,Repository中的类要以Repository结尾，否则注册失败
                //builder.RegisterAssemblyTypes(GetAssemblyByName("WXL.Repository")).Where(a => a.Name.EndsWith("Repository")).AsImplementedInterfaces();

                builder.RegisterGeneric(typeof(Foo<>)).As(typeof(IFoo<>))
                        .InstancePerLifetimeScope()
                        .PropertiesAutowired();
            }

            /// <summary>
            /// 根据程序集名称获取程序集
            /// </summary>
            /// <param name="AssemblyName">程序集名称</param>
            /// <returns></returns>
            public static Assembly GetAssemblyByName(String AssemblyName)
            {
                return Assembly.Load(AssemblyName);
            }
        }
    }

    public interface IFoobar<T1, T2>
    {
        T1 Foo { get; }
        T2 Bar { get; }
    }
    public interface IFoo<T> { }
    public interface IBar { }

    public class Foobar<T1, T2> : IFoobar<T1, T2>
    {
        public T1 Foo { get; private set; }
        public T2 Bar { get; private set; }
        public Foobar(T1 foo, T2 bar)
        {
            this.Foo = foo;
            this.Bar = bar;
        }
    }
    public class Foo<T> : IFoo<T> where T : class { }
    public class Bar : IBar { }

    public class Test
    {
        public int Hi = 0;
    }
}
